package com.google.io.lastcall.gwt.countdownclock.client;

import java.util.Date;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DisclosurePanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.VerticalPanel;


public class ChooseDate extends VerticalPanel {

	public static final int RECENT_ENTRIES=5;
	private HorizontalPanel mainPanel=new HorizontalPanel();
	private VerticalPanel recentPanel=new VerticalPanel();
	private VerticalPanel importantDatesPanel=new VerticalPanel();
	private PopupPanel popup;
	private HorizontalPanel submitHolder=new HorizontalPanel();
	private Button submit;
	private EditNumber year;
	private EditNumber month;
	private EditNumber day;
	private EditNumber hour;
	private EditNumber minute;
	private EditNumber second;
	private Label label=new Label();
	private Timer dismissTimer;
	private Date date;
	private final MyHandler handler=new MyHandler() {
		@Override
		public String receive(String info) {
			updateDate();
			return info;
		}
	  };

  @SuppressWarnings("deprecation")
public ChooseDate(final MyHandler SubmitHandler) {
	  super();
	  submit=new Button("Submit");
	  submit.addClickHandler(new ClickHandler() {
		@Override
		public void onClick(ClickEvent event) {
			if(date.getTime()>(new Date()).getTime()) {
				String str=date.toString();
				SubmitHandler.send(str);
				str=Long.toString(date.getTime());
				String[] strings=new String[RECENT_ENTRIES];
				strings[0]=str;
				int counter=1;
				for(int i=0;i<RECENT_ENTRIES;i++) {
					if(counter>=RECENT_ENTRIES) {
						break;
					} else {
						String cookie=Cookies.getCookie("__recentTimes_"+i);
						if(str.equals(cookie)) {
							continue;
						} else {
							strings[counter++]=cookie;
						}
					}
				}
				Date now=new Date();
				long time=now.getTime();
				time+=(365*(24*60*60*1000)); //set cookie for 1 year
				Date cookieDate=new Date(time);
				for(int i=0;i<RECENT_ENTRIES;i++) {
					if(strings[i]!=null) {
						Cookies.setCookie("__recentTimes_"+i,strings[i],cookieDate);
					}
				}
			} else {
				if(popup!=null) {
					dismissTimer.cancel();
					remove(popup);
					popup=null;
				}
				popup=new PopupPanel();
				Label error=new Label("Please Choose a Time In The Future");
				error.addStyleName("error");
				popup.add(error);
				add(popup);
				dismissTimer=new Timer() {
					@Override
					public void run() {
						remove(popup);
						popup=null;
					}
				};
				dismissTimer.schedule(5000);
			}
		}
	  });
	  submitHolder.setHorizontalAlignment(HorizontalPanel.ALIGN_RIGHT);
	  submitHolder.addStyleName("rightAlign");
	  submitHolder.setWidth("100%");
	  label.setHorizontalAlignment(ALIGN_LEFT);
	  submit.addStyleName("rightAlign");
	  submitHolder.add(label);
	  submitHolder.add(submit);
	  Date now = new Date();
	  int minYear=now.getYear()+1900;
	  int maxYear=minYear+11;
	  year=new EditNumber(minYear,minYear,maxYear,handler);
	  month=new EditNumber(5,1,13,handler,new MyHandler() {
		@Override
		public String receive(String info) {
			switch(Integer.parseInt(info)) {
			case 1:
				return "JAN";
			case 2:
				return "FEB";
			case 3:
				return "MAR";
			case 4:
				return "APR";
			case 5:
				return "MAY";
			case 6:
				return "JUN";
			case 7:
				return "JUL";
			case 8:
				return "AUG";
			case 9:
				return "SEP";
			case 10:
				return "OCT";
			case 11:
				return "NOV";
			case 12:
				return "DEC";
			default:
				return "ERR";
			}
		}
	  });
	  day=new EditNumber(10,1,32,handler);
	  hour=new EditNumber(9,0,24,handler);
	  minute=new EditNumber(0,0,60,handler);
	  second=new EditNumber(0,0,60,handler);
	  mainPanel.setVerticalAlignment(HorizontalPanel.ALIGN_MIDDLE);
	  mainPanel.add(hour);
	  Label colon=new Label(":");
	  colon.addStyleName("colon");
	  mainPanel.add(colon);
	  mainPanel.add(minute);
	  colon=new Label(":");
	  colon.addStyleName("colon");
	  mainPanel.add(colon);
	  mainPanel.add(second);
	  colon=new Label(" - ");
	  colon.addStyleName("colon");
	  mainPanel.add(colon);
	  mainPanel.add(month);
	  colon=new Label(":");
	  colon.addStyleName("colon");
	  mainPanel.add(colon);
	  mainPanel.add(day);
	  colon=new Label(":");
	  colon.addStyleName("colon");
	  mainPanel.add(colon);
	  mainPanel.add(year);
	  updateDate();
	  super.add(mainPanel);
	  super.add(submitHolder);
	  DisclosurePanel dp=new DisclosurePanel("Recent Dates: ");
	  dp.add(recentPanel);
	  dp.setOpen(false);
	  dp.addStyleName("disclosurePanel");
	  super.add(dp);
	  dp=new DisclosurePanel("Important Dates: ");
	  dp.add(importantDatesPanel);
	  dp.setOpen(false);
	  dp.addStyleName("disclosurePanel");
	  super.add(dp);
	  updatePanels();
  }
  @SuppressWarnings("deprecation")
private void updatePanels() {
	  for(int i=0;i<RECENT_ENTRIES;i++) {
		  final String cookie=Cookies.getCookie("__recentTimes_"+i);
		  if(cookie!=null&&!cookie.isEmpty()) {
			  try {
				Anchor a=new Anchor();
			  	final long longCookie=Long.parseLong(cookie);
			  	a.addClickHandler(new ClickHandler() {
				  @Override
					public void onClick(ClickEvent event) {
						fromLong(longCookie);
					} 
			  	});
			  	a.setHref("#");
			  	a.setText(new Date(longCookie).toString());
			  	recentPanel.add(a);
			  } catch(NumberFormatException e) {
				  continue;
			  }
		  }
	  }
	  String[][] important={
			  { "Google IO 2011","May 10 2011 09:00:00" },
			  { "First Day of Summer 2011","June 21 2011 00:00:00" },
			  { "Halloween 2011","October 31 2011 00:00:00" },
			  { "Thanksgiving 2011","November 24 2011 00:00:00" },
			  { "Hanukkah 2011","December 20 2011 00:00:00" },
			  { "Christmas 2011","December 25 2011 00:00:00" },
			  { "New Years 2012","January 1 2012 00:00:00" },
			  { "\"End of the World\" (Mayan Calendar ends)", "December 21 2012 00:00:00" }
	  };
	  for(int i=0;i<important.length;i++) {
		  String name=important[i][0];
		  Anchor a=new Anchor();
		  final Date myDate=new Date(important[i][1]);
		  a.addClickHandler(new ClickHandler() {
			  @Override
			  public void onClick(ClickEvent event) {
				  fromLong(myDate.getTime());
			  } 
		  });
		  a.setHref("#");
		  a.setText(name+" - "+myDate.toString());
		  importantDatesPanel.add(a);
	  }
  }
  public static native void alert(String msg) /*-{
  	$wnd.alert(msg);
  }-*/;
  @SuppressWarnings("deprecation")
  private void fromLong(Long l) {
	  Date d=new Date(l);
	  second.changeNumber(d.getSeconds());
	  minute.changeNumber(d.getMinutes());
	  hour.changeNumber(d.getHours());
	  day.changeNumber(d.getDate());
	  month.changeNumber(d.getMonth()+1);
	  year.changeNumber(d.getYear()+1900);
	  updateDate();
  }
  @SuppressWarnings("deprecation")
  private void updateDate() {
	  day.setMax(getMaxDays(month.getNumber(),year.getNumber())+1);
	  int yearInt=year.getNumber();
	  int monthInt=month.getNumber();
	  int dayInt=day.getNumber();
	  int hourInt=hour.getNumber();
	  int minuteInt=minute.getNumber();
	  int secondInt=second.getNumber();
	  String str = monthInt+"/"+dayInt+"/"+yearInt;
	  date=new Date(str);
	  long time=date.getTime();
	  date=new Date();
	  date.setTime(time+(hourInt*3600000)+(minuteInt*60000)+(secondInt*1000));
	  label.setText(date.toString());
  }
  private int getMaxDays(int month,int year) {
	  switch(month) {
	  case 1:
	  case 3:
	  case 5:
	  case 7:
	  case 8:
	  case 10:
	  case 12:
		  return 31;
	  case 2:
		  return isLeapYear(year)?29:28;
	  default:
		  return 30;
	  }
  }
  public static boolean isLeapYear(int year) {
	  if((year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0))) return true;
	  return false;
  }
}